//! 探索性数据分析模块
//! 
//! 用于探索性分析的函数

use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc, Datelike};
use ndarray::{Array1, Array2, ArrayView1};
use crate::objects::bar::RawBar;

/// 计算成交量加权平均价
pub fn vwap(price: &Array1<f64>, volume: &Array1<f64>) -> f64 {
    let total_volume: f64 = volume.sum();
    if total_volume == 0.0 {
        return 0.0;
    }
    
    let weighted_sum: f64 = price.iter().zip(volume.iter()).map(|(p, v)| p * v).sum();
    weighted_sum / total_volume
}

/// 计算时间加权平均价
pub fn twap(price: &Array1<f64>) -> f64 {
    price.mean().unwrap_or(0.0)
}

/// 去除beta对因子的影响
pub fn remove_beta_effects(
    df: &DataFrame,
    factor: &str,
    betas: &[String],
    linear_model: &str,
    linear_model_params: &HashMap<String, f64>,
) -> DataFrame {
    // TODO: 实现线性回归模型
    // 这里需要实现Ridge、LinearRegression、Lasso等模型
    unimplemented!("线性回归模型暂未实现");
}

/// 根据截面因子值构建多空组合
pub fn cross_sectional_strategy(
    df: &DataFrame,
    factor: &str,
    weight: &str,
    long: f64,
    short: f64,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现截面策略
    unimplemented!("截面策略暂未实现");
}

/// 判断因子方向
pub fn judge_factor_direction(
    df: &DataFrame,
    factor: &str,
    target: &str,
    by: &str,
    kwargs: &HashMap<String, serde_json::Value>,
) -> String {
    // TODO: 实现因子方向判断
    unimplemented!("因子方向判断暂未实现");
}

/// 计算单调性
pub fn monotonicity(sequence: &[f64]) -> f64 {
    if sequence.len() < 2 {
        return 0.0;
    }
    
    let mut increasing = 0;
    let mut decreasing = 0;
    
    for i in 1..sequence.len() {
        if sequence[i] > sequence[i-1] {
            increasing += 1;
        } else if sequence[i] < sequence[i-1] {
            decreasing += 1;
        }
    }
    
    let total = sequence.len() - 1;
    if total == 0 {
        return 0.0;
    }
    
    (increasing as f64 - decreasing as f64) / total as f64
}

/// 限制数值范围
pub fn min_max_limit(x: f64, min_val: f64, max_val: f64, digits: usize) -> f64 {
    let factor = 10.0_f64.powi(digits as i32);
    let rounded = (x * factor).round() / factor;
    rounded.max(min_val).min(max_val)
}

/// 滚动分层
pub fn rolling_layers(
    df: &DataFrame,
    factor: &str,
    n: usize,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现滚动分层
    unimplemented!("滚动分层暂未实现");
}

/// 计算年度天数
pub fn cal_yearly_days(dts: &[DateTime<Utc>], kwargs: &HashMap<String, serde_json::Value>) -> HashMap<i32, usize> {
    let mut yearly_days = HashMap::new();
    
    for dt in dts {
        let year = dt.year();
        *yearly_days.entry(year).or_insert(0) += 1;
    }
    
    yearly_days
}

/// 计算品种因子
pub fn cal_symbols_factor(
    df: &DataFrame,
    factor_function: fn(&[RawBar]) -> f64,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现品种因子计算
    unimplemented!("品种因子计算暂未实现");
}

/// 简单权重集成
pub fn weights_simple_ensemble(
    df: &DataFrame,
    weight_cols: &[String],
    method: &str,
    only_long: bool,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现权重集成
    unimplemented!("权重集成暂未实现");
}

/// 统一权重
pub fn unify_weights(df: &DataFrame, kwargs: &HashMap<String, serde_json::Value>) -> DataFrame {
    // TODO: 实现权重统一
    unimplemented!("权重统一暂未实现");
}

/// SMA多头熊市策略
pub fn sma_long_bear(df: &DataFrame, kwargs: &HashMap<String, serde_json::Value>) -> DataFrame {
    // TODO: 实现SMA多头熊市策略
    unimplemented!("SMA多头熊市策略暂未实现");
}

/// DIF多头熊市策略
pub fn dif_long_bear(df: &DataFrame, kwargs: &HashMap<String, serde_json::Value>) -> DataFrame {
    // TODO: 实现DIF多头熊市策略
    unimplemented!("DIF多头熊市策略暂未实现");
}

/// TSF类型判断
pub fn tsf_type(
    df: &DataFrame,
    factor: &str,
    n: usize,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现TSF类型判断
    unimplemented!("TSF类型判断暂未实现");
}

/// 限制杠杆
pub fn limit_leverage(
    df: &DataFrame,
    leverage: f64,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现杠杆限制
    unimplemented!("杠杆限制暂未实现");
}

/// 计算交易价格
pub fn cal_trade_price(
    df: &DataFrame,
    digits: Option<usize>,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现交易价格计算
    unimplemented!("交易价格计算暂未实现");
}

/// 标记CTA期间
pub fn mark_cta_periods(df: &DataFrame, kwargs: &HashMap<String, serde_json::Value>) -> DataFrame {
    // TODO: 实现CTA期间标记
    unimplemented!("CTA期间标记暂未实现");
}

/// 标记波动率
pub fn mark_volatility(
    df: &DataFrame,
    kind: &str,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现波动率标记
    unimplemented!("波动率标记暂未实现");
}

/// 制作价格特征
pub fn make_price_features(
    df: &DataFrame,
    price: &str,
    kwargs: &HashMap<String, serde_json::Value>,
) -> DataFrame {
    // TODO: 实现价格特征制作
    unimplemented!("价格特征制作暂未实现");
}

/// 计算换手率
pub fn turnover_rate(df: &DataFrame, kwargs: &HashMap<String, serde_json::Value>) -> DataFrame {
    // TODO: 实现换手率计算
    unimplemented!("换手率计算暂未实现");
}

/// 简化的DataFrame结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataFrame {
    pub columns: Vec<String>,
    pub data: Vec<Vec<serde_json::Value>>,
}

impl DataFrame {
    /// 创建新的DataFrame
    pub fn new(columns: Vec<String>) -> Self {
        Self {
            columns,
            data: Vec::new(),
        }
    }
    
    /// 添加行数据
    pub fn add_row(&mut self, row: Vec<serde_json::Value>) {
        if row.len() == self.columns.len() {
            self.data.push(row);
        }
    }
    
    /// 获取列索引
    pub fn get_column_index(&self, column: &str) -> Option<usize> {
        self.columns.iter().position(|col| col == column)
    }
    
    /// 获取列数据
    pub fn get_column(&self, column: &str) -> Option<Vec<serde_json::Value>> {
        let idx = self.get_column_index(column)?;
        Some(self.data.iter().map(|row| row[idx].clone()).collect())
    }
    
    /// 设置列数据
    pub fn set_column(&mut self, column: &str, values: Vec<serde_json::Value>) {
        if let Some(idx) = self.get_column_index(column) {
            for (i, value) in values.iter().enumerate() {
                if i < self.data.len() {
                    self.data[i][idx] = value.clone();
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ndarray::array;
    
    #[test]
    fn test_vwap() {
        let price = array![10.0, 11.0, 12.0];
        let volume = array![100.0, 200.0, 300.0];
        
        let result = vwap(&price, &volume);
        let expected = (10.0 * 100.0 + 11.0 * 200.0 + 12.0 * 300.0) / (100.0 + 200.0 + 300.0);
        
        assert!((result - expected).abs() < 1e-10);
    }
    
    #[test]
    fn test_twap() {
        let price = array![10.0, 11.0, 12.0];
        let result = twap(&price);
        let expected = (10.0 + 11.0 + 12.0) / 3.0;
        
        assert!((result - expected).abs() < 1e-10);
    }
    
    #[test]
    fn test_monotonicity() {
        let sequence = vec![1.0, 2.0, 3.0, 4.0, 5.0];
        let result = monotonicity(&sequence);
        assert_eq!(result, 1.0);
        
        let sequence = vec![5.0, 4.0, 3.0, 2.0, 1.0];
        let result = monotonicity(&sequence);
        assert_eq!(result, -1.0);
        
        let sequence = vec![1.0, 1.0, 1.0];
        let result = monotonicity(&sequence);
        assert_eq!(result, 0.0);
    }
    
    #[test]
    fn test_min_max_limit() {
        let result = min_max_limit(5.5, 0.0, 10.0, 2);
        assert_eq!(result, 5.5);
        
        let result = min_max_limit(-1.0, 0.0, 10.0, 2);
        assert_eq!(result, 0.0);
        
        let result = min_max_limit(15.0, 0.0, 10.0, 2);
        assert_eq!(result, 10.0);
    }
    
    #[test]
    fn test_cal_yearly_days() {
        let dts = vec![
            Utc.ymd(2023, 1, 1).and_hms(0, 0, 0),
            Utc.ymd(2023, 6, 15).and_hms(0, 0, 0),
            Utc.ymd(2024, 1, 1).and_hms(0, 0, 0),
        ];
        
        let result = cal_yearly_days(&dts, &HashMap::new());
        
        assert_eq!(result.get(&2023), Some(&2));
        assert_eq!(result.get(&2024), Some(&1));
    }
} 